package agent

import (
	"context"
	"sync"
	"sync/atomic"
	"time"

	"github.com/google/uuid"
	"techoiceness.com/aiagent/llm-gateway/internal/llm"
	"techoiceness.com/aiagent/llm-gateway/internal/repository"
	"techoiceness.com/aiagent/llm-gateway/internal/tools"
)

type AgentHub struct {
	mux sync.RWMutex

	agents map[string]*Agent // key: conversationID的字符串形式

	repo repository.LLMMessageRepository

	llmProviderManager *llm.ProviderManager // provider管理器
	toolManager        *tools.ToolManager

	systemPrompt     string                            // 当前激活的全局系统提示词（缓存）
	systemPromptRepo repository.SystemPromptRepository // 系统提示词仓库
}

type AgentHubOption func(*AgentHub)

// WithProviderManager 设置LLM提供者管理器
func WithProviderManager(llmProviderManager *llm.ProviderManager) AgentHubOption {
	return func(h *AgentHub) {
		h.llmProviderManager = llmProviderManager
	}
}

// WithRepository 设置会话存储库
func WithRepository(repo repository.LLMMessageRepository) AgentHubOption {
	return func(h *AgentHub) {
		h.repo = repo
	}
}

// WithToolManager 设置工具管理器
func WithToolManager(toolManager *tools.ToolManager) AgentHubOption {
	return func(h *AgentHub) {
		h.toolManager = toolManager
	}
}

// WithSystemPrompt 设置全局系统提示词（用于回退）
func WithSystemPrompt(prompt string) AgentHubOption {
	return func(h *AgentHub) {
		h.systemPrompt = prompt
	}
}

// WithSystemPromptRepository 设置系统提示词仓库
func WithSystemPromptRepository(repo repository.SystemPromptRepository) AgentHubOption {
	return func(h *AgentHub) {
		h.systemPromptRepo = repo
	}
}

func NewAgentHub(opts ...AgentHubOption) *AgentHub {
	hub := &AgentHub{
		agents: make(map[string]*Agent),
	}

	for _, opt := range opts {
		opt(hub)
	}

	// 启动时从数据库加载系统提示词
	hub.loadSystemPromptFromDB()

	return hub
}

func (h *AgentHub) GetOrCreateAgent(conversationID uuid.UUID) *Agent {
	h.mux.Lock()
	defer h.mux.Unlock()

	conversationIDStr := conversationID.String()
	if agent, exists := h.agents[conversationIDStr]; exists {
		return agent
	}

	agent := NewAgent(
		conversationID,
		h.llmProviderManager,
		h.repo,
	)

	if h.toolManager != nil {
		agent.SetToolManager(h.toolManager)
	}

	// 设置当前激活的系统提示词
	if h.systemPrompt != "" {
		agent.SetSystemPrompt(h.systemPrompt)
	}

	h.agents[conversationIDStr] = agent
	return agent
}

func (h *AgentHub) CleanupAgents() {
	h.mux.Lock()
	defer h.mux.Unlock()

	currentTime := time.Now().Unix()
	for id, agent := range h.agents {
		if atomic.LoadInt64(&agent.lastActiveTime) < currentTime-600 {
			// 如果最后活跃时间超过10分钟，则删除该agent
			delete(h.agents, id)
		}
	}
}

// SetSystemPrompt 设置全局系统提示词
// 只会更新没有消息的agent的系统提示词
func (h *AgentHub) SetSystemPrompt(prompt string) {
	h.mux.Lock()
	defer h.mux.Unlock()

	h.systemPrompt = prompt

	// 只更新没有消息记录的agent的系统提示词
	for _, agent := range h.agents {
		if !agent.HasMessages() {
			agent.SetSystemPrompt(prompt)
		}
	}
}

// loadSystemPromptFromDB 从数据库加载当前激活的系统提示词
func (h *AgentHub) loadSystemPromptFromDB() {
	if h.systemPromptRepo == nil {
		return
	}

	ctx := context.Background()
	systemPrompt, err := h.systemPromptRepo.GetActiveSystemPrompt(ctx)
	if err != nil {
		// 如果数据库中没有激活的系统提示词，就不使用系统提示词
		h.systemPrompt = ""
		return
	}

	h.systemPrompt = systemPrompt.Content
}

// ReloadSystemPromptFromDB 重新从数据库加载系统提示词（用于管理端更新后刷新）
func (h *AgentHub) ReloadSystemPromptFromDB() error {
	if h.systemPromptRepo == nil {
		return nil
	}

	ctx := context.Background()
	systemPrompt, err := h.systemPromptRepo.GetActiveSystemPrompt(ctx)
	if err != nil {
		// 如果没有激活的系统提示词，清空当前设置
		h.mux.Lock()
		h.systemPrompt = ""
		// 清空所有没有消息的agent的系统提示词
		for _, agent := range h.agents {
			if !agent.HasMessages() {
				agent.SetSystemPrompt("")
			}
		}
		h.mux.Unlock()
		return nil // 不返回错误，因为没有系统提示词是正常情况
	}

	h.mux.Lock()
	defer h.mux.Unlock()

	h.systemPrompt = systemPrompt.Content

	// 更新所有没有消息的agent
	for _, agent := range h.agents {
		if !agent.HasMessages() {
			agent.SetSystemPrompt(h.systemPrompt)
		}
	}

	return nil
}

// GetCurrentSystemPrompt 获取当前激活的系统提示词内容
func (h *AgentHub) GetCurrentSystemPrompt() string {
	h.mux.RLock()
	defer h.mux.RUnlock()
	return h.systemPrompt
}
